package org.ktx.osr.upload

import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.asRequestBody
import org.ktx.osr.data.UploadConfig
import org.ktx.osr.data.UploadResult
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit

/**
 * 文件上传管理器
 */
class FileUploadManager(private val context: Context) {
    
    companion object {
        private const val TAG = "FileUploadManager"
    }
    
    private val client = OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(60, TimeUnit.SECONDS)
        .readTimeout(60, TimeUnit.SECONDS)
        .build()
    
    /**
     * 上传文件
     * @param file 要上传的文件
     * @param config 上传配置
     * @param onProgress 进度回调
     * @return 上传结果
     */
    suspend fun uploadFile(
        file: File,
        config: UploadConfig,
        onProgress: ((progress: Int) -> Unit)? = null
    ): UploadResult = withContext(Dispatchers.IO) {
        try {
            Log.d(TAG, "开始上传文件: ${file.name}")
            Log.d(TAG, "文件大小: ${file.length()} bytes")
            Log.d(TAG, "服务器地址: ${config.serverUrl}")
            
            if (!file.exists()) {
                return@withContext UploadResult(
                    success = false,
                    errorMessage = "文件不存在: ${file.absolutePath}"
                )
            }
            
            val requestBody = createMultipartBody(file, onProgress)
            val request = buildRequest(config, requestBody)
            
            val response = client.newCall(request).execute()
            
            if (response.isSuccessful) {
                val responseBody = response.body?.string()
                Log.d(TAG, "上传成功，服务器响应: $responseBody")
                
                // 解析服务器响应，获取文件URL
                val fileUrl = parseFileUrl(responseBody)
                
                UploadResult(
                    success = true,
                    originalFileUrl = fileUrl
                )
            } else {
                val errorMessage = "上传失败: ${response.code} ${response.message}"
                Log.e(TAG, errorMessage)
                UploadResult(
                    success = false,
                    errorMessage = errorMessage
                )
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "上传文件时发生异常", e)
            UploadResult(
                success = false,
                errorMessage = "上传异常: ${e.message}"
            )
        }
    }
    
    /**
     * 批量上传文件
     */
    suspend fun uploadFiles(
        files: List<File>,
        config: UploadConfig,
        onProgress: ((fileIndex: Int, progress: Int) -> Unit)? = null
    ): List<UploadResult> = withContext(Dispatchers.IO) {
        val results = mutableListOf<UploadResult>()
        
        files.forEachIndexed { index, file ->
            val result = uploadFile(file, config) { progress ->
                onProgress?.invoke(index, progress)
            }
            results.add(result)
        }
        
        results
    }
    
    /**
     * 创建多部分请求体
     */
    private fun createMultipartBody(
        file: File,
        onProgress: ((progress: Int) -> Unit)?
    ): RequestBody {
        val mediaType = getMediaType(file)
        val fileBody = file.asRequestBody(mediaType)
        
        return if (onProgress != null) {
            // 带进度回调的请求体
            ProgressRequestBody(fileBody) { progress ->
                onProgress(progress)
            }
        } else {
            fileBody
        }
    }
    
    /**
     * 构建请求
     */
    private fun buildRequest(config: UploadConfig, requestBody: RequestBody): Request {
        val builder = Request.Builder()
            .url(config.serverUrl)
            .post(requestBody)
        
        // 添加API密钥（如果提供）
        config.apiKey?.let { apiKey ->
            builder.addHeader("Authorization", "Bearer $apiKey")
        }
        
        // 添加其他必要的头部
        builder.addHeader("User-Agent", "OSR-App/1.0")
        
        return builder.build()
    }
    
    /**
     * 获取文件的媒体类型
     */
    private fun getMediaType(file: File): MediaType {
        return when (file.extension.lowercase()) {
            "mp4" -> "video/mp4".toMediaType()
            "webm" -> "video/webm".toMediaType()
            "aac" -> "audio/aac".toMediaType()
            "wav" -> "audio/wav".toMediaType()
            "mp3" -> "audio/mpeg".toMediaType()
            else -> "application/octet-stream".toMediaType()
        }
    }
    
    /**
     * 解析服务器响应中的文件URL
     */
    private fun parseFileUrl(responseBody: String?): String? {
        if (responseBody.isNullOrEmpty()) return null
        
        try {
            // 这里应该根据实际的服务器响应格式来解析
            // 示例：假设服务器返回JSON格式 {"url": "http://example.com/file.mp4"}
            // 实际实现需要根据服务器API文档来调整
            
            // 简单的URL提取（假设响应就是URL）
            if (responseBody.startsWith("http")) {
                return responseBody.trim()
            }
            
            // 如果是JSON格式，可以使用JSON解析库
            // 这里只是示例，实际需要根据服务器响应格式调整
            return null
            
        } catch (e: Exception) {
            Log.w(TAG, "解析文件URL失败", e)
            return null
        }
    }
    
    /**
     * 带进度的请求体
     */
    private class ProgressRequestBody(
        private val requestBody: RequestBody,
        private val onProgress: (progress: Int) -> Unit
    ) : RequestBody() {
        
        override fun contentType(): MediaType? = requestBody.contentType()
        
        override fun contentLength(): Long = requestBody.contentLength()
        
        override fun writeTo(sink: okio.BufferedSink) {
            val countingSink = object : okio.ForwardingSink(sink) {
                private var bytesWritten = 0L
                private val contentLength = contentLength()
                
                override fun write(source: okio.Buffer, byteCount: Long) {
                    super.write(source, byteCount)
                    bytesWritten += byteCount
                    
                    if (contentLength > 0) {
                        val progress = ((bytesWritten * 100) / contentLength).toInt()
                        onProgress(progress)
                    }
                }
            }
            
            val bufferedSink = okio.Buffer().apply { 
                requestBody.writeTo(this)
            }
            
            // 将缓冲的数据写入到计数sink
            bufferedSink.readAll(countingSink)
        }
    }
}
